﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using TheGameClient.Processes;
using Waaahsabi.Controls.DWM;
using Waaahsabi.Controls.TheGame;

namespace TheGameClient
{
	public class ProgramTbpaBypass : IProgram
	{
		private SecSysTbpaControl _bypassedControl;
		private bool _operationResult;
		private UIElement _rootObject;
		private double _speed;
		private TheGameWindow _topmostWindow;

		#region IProgram Members

		public ulong InterfaceId
		{
			get { return new Guid("1BF176C0-1876-4908-8909-E344A96360E3").ToLong(); }
		}

		public Guid ProcessId { get; private set; }
		public ProgramState State { get; private set; }
		public int Version { get; set; }
		public GenericTargetingControl Control { get; private set; }

		public string ProcessName
		{
			get { return "Timed Brainwave Pattern bypass"; }
		}

		public InterfaceCategory Category
		{
			get { return InterfaceCategory.Program; }
		}

		public ulong ProgramId { get; set; }
		public bool IsInitialized { get; private set; }

		public void Initialize()
		{
			ProcessId = Guid.NewGuid();
			GenericTargetingControl ctrl = new GenericTargetingControl(true);
			ctrl.ControlMoving += CtrlMoving;
			ctrl.Label = string.Format("{0} v{1}.0", ProcessName, Version);
			ctrl.Drop += CtrlDrop;
			ctrl.QuitButtonClick += CtrlQuitButtonClick;
			ctrl.StatusText = "Initializing";
			Control = ctrl;
			ProgramManager.Instance.RegisterProcess(this);
			ProgramManager.Instance.GetSpeedForProcessCompleted += ProgramManagerGetSpeedForProcessCompleted;
			ProgramManager.Instance.GetSpeed(ProcessId);
		}

		public void Execute()
		{
			Control.StatusText = "Bypassing security system...";
			Control.AnimationCompleted += ControlAnimationCompleted;
			Control.ShowReverseProgressAnimation(_speed); //slow is 1 / 8, fast is 1 * 8
		}

		public void SetOperationResult(bool successful)
		{
			_operationResult = successful;
			Control.InterruptAnimation();
			if (_operationResult)
			{
				Control.StatusText = "Bypass successful.";
				_bypassedControl.State = SecuritySystemState.Bypassed;
			}
			else
			{
				Control.StatusText = "Bypass failed";
				_bypassedControl.State = SecuritySystemState.None;
			}
		}

		#endregion

		private void ProgramManagerGetSpeedForProcessCompleted(object sender, GetSpeedEventArgs e)
		{
			Control.StatusText = "Drag onto retinal scan checking UI to start bypass.";
			_speed = e.Speed;
		}

		private void CtrlMoving(object sender, MouseEventArgs e)
		{
			if (_rootObject == null)
			{
				var controlParent = VisualTreeHelper.GetParent(Control);
				_rootObject = VisualTreeHelper.GetParent(controlParent) as UIElement;
			}

			var hitElements =
				VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), _rootObject).OfType<TheGameWindow>();
			if (hitElements.Count() > 0)
			{
				TheGameWindow wnd = hitElements.First();
				if (!wnd.IsFocused)
					wnd.Focus();
				_topmostWindow = wnd;
			}
		}

		private void CtrlQuitButtonClick(object sender, RoutedEventArgs e)
		{
			var controlParent = VisualTreeHelper.GetParent(Control);
			if (controlParent is Canvas)
				((Canvas) controlParent).Children.Remove(Control);
		}

		private void CtrlDrop(object sender, MouseButtonEventArgs e)
		{
			if (_topmostWindow == null)
				return;
			GenericSystemInterface gsi =
				VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), _topmostWindow).OfType<GenericSystemInterface>().
					FirstOrDefault();
			if (gsi == null) //this means we're not executed in a remote connection window anyways
				return;

			var targetElements =
				VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), gsi).OfType<SecSysTbpaControl>();
			if (targetElements.Count() > 0)
			{
				SecSysTbpaControl ctrl = targetElements.First();
				if (ctrl.State == SecuritySystemState.Bypassed || ctrl.State == SecuritySystemState.Bypassing ||
				    ctrl.State == SecuritySystemState.Accessed)
					return;
				ctrl.State = SecuritySystemState.Bypassing;
				_bypassedControl = ctrl;
				Execute();
			}
			else
			{
				_operationResult = false;
				return;
			}
		}

		private void ControlAnimationCompleted(object sender, EventArgs e)
		{
			Control.AnimationCompleted -= ControlAnimationCompleted;
			_bypassedControl.Bypass(this);
		}
	}

	public class ProgramTbpaBypassFactory : UiFactoryBase
	{
		public override InterfaceCategory UiCategory
		{
			get { return InterfaceCategory.Program; }
		}

		public override IProcess CreateProgram()
		{
			return new ProgramTbpaBypass();
		}
	}
}